package com.gitee.sparta.core.cluster.strategy;

import com.gitee.sparta.core.bean.cluster.ClusterCmd;
import com.gitee.sparta.common.helpers.IsolationHelper;
import com.gitee.sparta.core.bean.cluster.ClusterProtocol;
import com.gitee.sparta.core.cluster.ClusterCache;
import com.gitee.sparta.core.cluster.balance.LoadBalance;
import com.gitee.sparta.core.property.SpartaCoreProperties;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;

import java.nio.channels.SocketChannel;
import java.util.Objects;

/**
 * <p>
 *      follower 连接恢复，允许消费消息
 * </p>
 *
 * @author zyred
 * @since v 0.0.2
 */
@Slf4j
public class FollowerRecoverStrategy extends Strategy {

    public FollowerRecoverStrategy(RedissonClient client,
                                 LoadBalance loadBalance,
                                 SpartaCoreProperties properties) {
        super(client, loadBalance, properties);
    }

    @Override
    public void handle(ChannelHandlerContext ctx, SocketChannel sc, ClusterProtocol cp) {

        log.info("[Sparta] Follower recover, sid: {}", cp.getServerId());

        // 连接恢复，查看 leader 缓存中是否存在 channel
        // 如果没有缓存 channel， 么就重新走一次 accept 的流程注册 follower
        Integer sid = ClusterCache.getSid(ctx.channel());
        if (Objects.isNull(sid)) {
            Strategy strategy = StrategyFactory.getStrategy(ClusterCmd.CHANNEL_ACCEPT);
            strategy.handle(ctx, sc, cp);
            return;
        }

        // 如果有了，就直接允许消费消息
        this.loadBalance.addNode(IsolationHelper
                .isolation(cp.getServerId()), cp.getServerId());
    }
}
